接下來要做上方Banner
原APP上方有個輪播裝置
負責打廣告或是顯示優惠
在APP也是時常出現
呈現方式很多種都可以做出來
可以使用collectionView
或是scrollView+pageControl
但我之前在OC寫的都是用scrollView+pageControl
之前OC 實作Banner
效果也有左右滑動
點擊事件以及單獨新建一個class去呼叫
但是現在Swfit功力太淺
先做出來再說
因為我們要使用ScrollView
所以先把UIScrollViewDelegate
設定好
currentIndex
紀錄目前的indeximageArray
圖片名稱儲存在這裡timer
幾秒切換下一張leftImageView, rightImageView, currentImageView
宣告三個是為了 你在滑動前後需要預載圖片 才不會滑動後還要等待用意class ViewController: UIViewController,UIScrollViewDelegate {
let width = UIScreen.main.bounds.size.width
var currentIndex : NSInteger = 0
var leftImageView = UIImageView()
var rightImageView = UIImageView()
var currentImageView = UIImageView()
var imageArray = [String]()
var timer = Timer()
這裡將scrollView 範圍寬度已手機寬度3倍
設定好
並且將剛剛三張圖片
平均分布在scrollView的三等份裡面
// 上方banner
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.contentSize = CGSize(width: width * 3, height: 200)
scrollView.contentOffset = CGPoint(x: width, y: 50)
scrollView.isPagingEnabled = true
scrollView.frame = CGRect(x: 0, y: 50, width: width, height: 200)
rightImageView.frame = CGRect(x: width * 2, y: 50, width: width, height: 200)
currentImageView.frame = CGRect(x: width * 1, y: 50, width: width, height: 200)
leftImageView.frame = CGRect(x: width * 0, y: 50, width: width, height: 200)
scrollView.addSubview(rightImageView)
scrollView.addSubview(currentImageView)
scrollView.addSubview(leftImageView)
scrollView.delegate = self
return scrollView
}()
pageControl 負責頁數
以及下方小圓點
顏色部分
currentPageIndicatorTintColor
選取時pageIndicatorTintColor
為選取時位置部分設置在scrollView
的maxY
並且扣掉自己的高度
// 下方小圓點
lazy var pageControl: UIPageControl = {
let pageControl = UIPageControl()
pageControl.frame = CGRect(x: 0, y: scrollView.frame.maxY-20, width: width, height: 20)
pageControl.backgroundColor = UIColor.clear
//小圓點選取時顏色
pageControl.currentPageIndicatorTintColor = UIColor.init(displayP3Red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
//小圓點未選取顏色
pageControl.pageIndicatorTintColor = UIColor.init(displayP3Red: 1.0, green: 1.0, blue: 1.0, alpha: 0.2)
pageControl.numberOfPages = imageArray.count
pageControl.currentPage = 0
return pageControl
}()
每次pageView
變動時
更新三個imageView
並且將scrollView setContentOffset
移動回來中間
因為剛剛已經移動過了
/**
* 更新圖片
*/
func reloadImage(){
var leftIndex = 0
var rightIndex = 0
currentIndex = currentIndex % imageArray.count
scrollView.setContentOffset(CGPoint(x: width, y: 50), animated: false)
pageControl.currentPage = (currentIndex - 1 + imageArray.count) % imageArray.count //防止越界
leftIndex = (currentIndex - 1 + imageArray.count) % imageArray.count //防止越界
rightIndex = (currentIndex + 1) % imageArray.count
rightImageView.image = UIImage(named: imageArray[rightIndex])
currentImageView.image = UIImage(named: imageArray[currentIndex])
leftImageView.image = UIImage(named: imageArray[leftIndex])
}
這裡就設定每2秒更新
一次
並且讓index + 1
/**
* 更新timer
*/
func setupTimer() {
timer = Timer.scheduledTimer(timeInterval: 2,target:self,selector:#selector(timeChanged),userInfo:nil,repeats:true)
RunLoop.current.add(timer, forMode: RunLoop.Mode.common)
}
/**
* time 事件
*/
@objc func timeChanged(){
currentIndex = currentIndex + 1
//更新圖片+scrollView
reloadImage()
}
因為剛剛有設置 scrollView
的delegate
所以可以監聽一些事件
scrollViewWillBeginDragging
滑動開始時scrollViewDidEndDecelerating
滑動結束時這邊開始
時需要停止timer
因為滑動的時候就不用自動輪播
不然會衝突到 使用者體驗不好
停止
時 判斷位置
是否偏向於某一邊
如果是的話+1 或是 -1
往前或是往後
/**
* scrollView 滑動開始監聽
*/
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
timer.invalidate()
}
/**
* scrollView 滑動坄停止監聽
*/
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
//向右拖動
if scrollView.contentOffset.x > width {
currentIndex = (currentIndex + 1) % imageArray.count
}
//向左拖動
if scrollView.contentOffset.x < width{
currentIndex = (currentIndex - 1 + imageArray.count) % imageArray.count
}
//更新小圓點當前位置
pageControl.currentPage = (currentIndex - 1 + imageArray.count) % imageArray.count
reloadImage()
setupTimer()
}
最後全部設置好後
將圖片塞進 imageArray
並且 addSubview
打開 timer
圖片部分我先截圖Uber eat
然後修完圖了 可以到Github看
override func viewDidLoad() {
super.viewDidLoad()
imageArray = ["banner1","banner2","banner3","banner4","banner5","banner6","banner7"]
self.view.addSubview(self.scrollView)
self.view.addSubview(self.pageControl)
reloadImage()
setupTimer()
}
Demo
看起來還不錯
只差塞回去collectionView
以及換頁特效
Github連結:
https://github.com/Bgihe/BannerTest
程式碼中的 scrollViewDidEndDecelerating 好像不會被 call 到